package org.budo.maven.plugin.assembly.mojo.processor;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.project.MavenProject;
import org.budo.maven.plugin.assembly.mojo.util.MojoGitLogUtil;
import org.budo.support.lang.util.FileUtil;
import org.budo.support.lang.util.IoUtil;
import org.budo.support.lang.util.StringUtil;

/**
 * @author lmw
 */
public class BudoMavenAssemblyWarProcessor extends AbstractBudoMavenAssemblyProcessor {
    public BudoMavenAssemblyWarProcessor(MavenProject project, MavenSession session, String format, Log log) {
        super(project, session, format, log);
    }

    @Override
    public void execute() throws Throwable {
        this.getLog().info("#27 BudoMavenAssemblyWarProcessor#execute project.artifact=" + this.getProject().getArtifact() //
                + ", project.base=" + this.getProject().getBasedir() + ", format=" + this.getFormat() + ", this=" + this);

        // 清理目标文件夹
        String destPath = this.getProject().getBuild().getDirectory() + File.separator + this.getProject().getArtifactId() + "-assembly";
        FileUtil.deleteIfExists(destPath);

        // 写入git版本，到conf
        MojoGitLogUtil.writeGitLogToConf(this.getProject(), this.getLog());

        // 复制war
        this.copyWarDir();

        // 复制bin
        this.writeBin();

        // 复制 Docker
        this.writeDocker();

        // 将自身Jar包 去掉resources后 放入lib
        // this._copySelfWar(); // war 项目

        this.writeReadme();

        // 压缩
        this.compress();
    }

    protected void _copySelfWar() throws Exception {
        String target = this.getProject().getBuild().getDirectory();

        String jarName = this.getProject().getArtifactId() + "-" + this.getProject().getVersion() + ".jar";

        File jarTo = new File(target //
                + File.separator + this.getProject().getArtifactId() + "-assembly" //
                + File.separator + "lib" //
                + File.separator + jarName);

        File classesDir = new File(target, "classes");

        this.getLog().info("#251 _copySelfWar, from " + FileUtil.getCanonicalPath(classesDir) + ", to " + FileUtil.getCanonicalPath(jarTo));

        ZipOutputStream zipOut = new ZipOutputStream(IoUtil.fileOutputStream(jarTo));

        this.doCopySelfWar(classesDir, zipOut, null);

        zipOut.close();
    }

    private void doCopySelfWar(File dir, ZipOutputStream zipOut, String path) throws IOException {
        File[] listFiles = dir.listFiles();
        for (File file : listFiles) {
            String entryPath = StringUtil.isEmpty(path) ? file.getName() : path + File.separator + file.getName();
            if (file.isDirectory()) {
                this.doCopySelfWar(file, zipOut, entryPath); // 递归
            } else {
                String resourcePath = this.findInResource(entryPath);
                if (null != resourcePath) { // 新的 jar 中跳过 resources 里面的文件
                    this.getLog().debug("#279 skip resource file " + file + ", " + resourcePath);
                    continue;
                }

                this.getLog().debug("#283 add selfJar entry " + file);

                zipOut.putNextEntry(new ZipEntry(entryPath));
                InputStream inputStream = IoUtil.fileInputStream(file);
                IoUtil.write(inputStream, zipOut, false, true);
                zipOut.closeEntry();
            }
        }
    }

    private void copyWarDir() {
        String target = this.getProject().getBuild().getDirectory();
        String finalName = this.getProject().getBuild().getFinalName();
        String artifactId = this.getProject().getArtifactId();

        File from = new File(target + File.separator + finalName);

        File assemblyDir = new File(target + File.separator + artifactId + "-assembly");
        File to = new File(FileUtil.getCanonicalPath(assemblyDir) + File.separator + "webapp");

        FileUtil.copyDir(from, to);

        this.getLog().info("#83 after copyWar, from " + FileUtil.getCanonicalPath(from) + " to " + FileUtil.getCanonicalPath(to));
    }
}